//+------------------------------------------------------------------+
//|                                                    SignalSAR.mqh |
//|                             Copyright 2000-2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert/ExpertSignal.h>    // 专家顾问信号基类（提供信号生成框架）

// wizard description start（MQL5 策略向导描述，用于识别类信息与参数）
//+------------------------------------------------------------------+
//| 类功能描述                                                       |
//| Title=基于抛物线转向指标（Parabolic SAR）的交易信号               |
//| Type=SignalAdvanced                                              |
//| Name=Parabolic SAR                                               |
//| ShortName=SAR                                                    |
//| Class=CSignalSAR                                                 |
//| Page=signal_sar                                                  |
//| Parameter=Step,double,0.02,步长（SAR 加速因子增量）                |
//| Parameter=Maximum,double,0.2,最大值（SAR 加速因子上限）            |
//+------------------------------------------------------------------+
// wizard description end

//+------------------------------------------------------------------+
//| CSignalSAR 类：基于抛物线转向指标（Parabolic SAR）的交易信号生成器  |
//| 核心能力：继承自 CExpertSignal，通过调用 SAR 指标（随价格移动的“跟踪止损式”指标）， |
//|           识别2类多空信号（价格与SAR位置关系、SAR转向切换），         |
//|           支持通过“信号权重”调整不同形态的优先级，适配趋势跟踪与止损场景   |
//| 核心逻辑：SAR 计算公式基于“加速因子（AF）”动态调整，价格上涨时AF从步长递增至最大值， |
//|           SAR在价格下方（支撑位）；价格下跌时AF反向递增，SAR在价格上方（压力位）； |
//|           通过“SAR与价格的相对位置”“SAR跨越价格的转向动作”判断信号       |
//| 适用场景：中短线趋势跟踪（SAR 擅长“跟势不逆势”，自动锁定盈利），适合股票、期货、外汇等 |
//|           品种，可单独作为趋势信号源或止损参考工具                     |
//+------------------------------------------------------------------+
class CSignalSAR : public CExpertSignal
  {
protected:
   // 核心组件与参数（保护，子类可访问）
   CiSAR             m_sar;            // SAR 指标对象（封装抛物线转向指标的计算与数据读取）
   // SAR 指标可调参数（与指标原生参数对应，默认配置为经典参数组合）
   double            m_step;           // 步长（加速因子增量，默认0.02，每次趋势延续时AF增加的值）
   double            m_maximum;        // 最大值（加速因子上限，默认0.2，AF的最大取值，防止过度加速）
   // 市场形态信号权重（0-100，值越大信号优先级越高，默认配置突出SAR转向信号）
   int               m_pattern_0;      // 形态0权重：SAR在价格的预期侧（如多单需SAR在价格下方）
   int               m_pattern_1;      // 形态1权重：SAR发生转向切换（如SAR从价格上方跨越至下方→多单）

public:
   //----------------------------------------------------------------
   // 构造与析构函数
   //----------------------------------------------------------------
   /**
    * @brief 构造函数：初始化 SAR 信号生成器
    * @details 1. 初始化 SAR 指标对象及默认参数（步长=0.02，最大值=0.2，经典趋势跟踪配置）；
    *          2. 设置默认信号权重（形态0=40，形态1=90，突出转向信号的强趋势意义）；
    *          3. 启用收盘价序列（m_used_series=USE_SERIES_CLOSE），因信号判断核心依赖收盘价与SAR的位置关系；
    *          4. 继承父类 CExpertSignal 的信号框架初始化
    */
                     CSignalSAR(void);

   /**
    * @brief 析构函数：清理 SAR 信号生成器资源
    * @details 释放 SAR 指标对象占用的内存，依赖父类析构逻辑完成信号框架资源清理
    */
                    ~CSignalSAR(void);

   //----------------------------------------------------------------
   // SAR 指标参数配置：修改核心指标参数（外部调用接口）
   //----------------------------------------------------------------
   /**
    * @brief 设置 SAR 加速因子步长（核心参数）
    * @param value [in] 步长值（建议0.01-0.05，值越小SAR随价格移动越慢，趋势跟踪越平滑；值越大反应越快但易产生假信号）
    */
   void              Step(double value);

   /**
    * @brief 设置 SAR 加速因子最大值（核心参数）
    * @param value [in] 最大值（建议0.1-0.3，值越小限制加速幅度，适合慢趋势；值越大允许更快加速，适合快趋势）
    */
   void              Maximum(double value);

   //----------------------------------------------------------------
   // 信号权重配置：修改不同市场形态的信号强度（外部调用接口）
   //----------------------------------------------------------------
   /**
    * @brief 设置形态0（SAR与价格位置关系）的信号权重
    * @param value [in] 权重值（0-100，建议30-50，值越大越重视SAR对当前趋势的确认作用）
    */
   void              Pattern_0(int value);

   /**
    * @brief 设置形态1（SAR转向切换）的信号权重
    * @param value [in] 权重值（0-100，建议80-100，值越大越重视SAR提示的趋势反转/启动信号）
    */
   void              Pattern_1(int value);

   //----------------------------------------------------------------
   // 参数验证：确保指标参数与信号配置有效（信号生成前提）
   //----------------------------------------------------------------
   /**
    * @brief 验证 SAR 指标参数与信号配置的有效性
    * @return bool - 验证结果：true=所有参数有效，false=存在无效参数（由父类验证基础配置）
    * @note 验证逻辑：
    *       1. 调用父类 ValidationSettings() 验证信号框架基础参数（如品种、周期、价格序列可用性）；
    *       2. SAR 核心参数（步长、最大值）由指标内部兼容非负值，此处不额外验证（实际使用中建议步长>0且≤最大值）
    */
   virtual bool      ValidationSettings(void);

   //----------------------------------------------------------------
   // 指标初始化：创建并注册 SAR 指标（信号生成的前提）
   //----------------------------------------------------------------
   /**
    * @brief 初始化 SAR 指标及信号所需的价格序列数据
    * @param indicators [in] 指标集合对象（用于管理所有策略用到的指标，如 SAR、成交量等）
    * @return bool - 初始化结果：true=成功（指标创建+注册到指标集合），false=失败
    * @note 调用流程：
    *       1. 先调用父类 InitIndicators() 完成基础信号框架与收盘价序列初始化；
    *       2. 调用内部 InitSAR() 方法创建 SAR 指标，绑定当前品种、周期及核心参数（步长、最大值）；
    *       3. 若指标创建失败（如参数无效、品种不支持），返回 false 并终止信号生成
    */
   virtual bool      InitIndicators(CIndicators *indicators);

   //----------------------------------------------------------------
   // 信号判断核心方法：生成多空信号权重（策略决策依据）
   //----------------------------------------------------------------
   /**
    * @brief 判断当前市场是否满足多单（买入）开仓条件，返回信号权重
    * @return int - 多单信号权重（0-100，0=无信号，值越大信号越强烈）
    * @note 核心判断逻辑（基于 SAR 趋势跟踪特性）：
    *       1. 基础过滤：若当前K线收盘价 < SAR（SAR在价格上方，空头趋势），直接返回0（无多单信号）；
    *       2. 形态0（位置确认）：当前K线收盘价 > SAR（SAR在价格下方，支撑位），返回形态0权重（趋势确认）；
    *       3. 形态1（转向信号）：前一根K线收盘价 < SAR（SAR曾在价格上方），当前K线收盘价 > SAR（SAR切换至下方），
    *          说明SAR完成“空头→多头”转向，直接返回形态1权重（优先级最高）；
    *       4. 信号优先级：形态1 > 形态0（转向信号标志趋势启动/反转，权重更高）
    */
   virtual int       LongCondition(void);

   /**
    * @brief 判断当前市场是否满足空单（卖出）开仓条件，返回信号权重
    * @return int - 空单信号权重（0-100，0=无信号，值越大信号越强烈）
    * @note 核心判断逻辑（基于 SAR 趋势跟踪特性，与多单相反）：
    *       1. 基础过滤：若当前K线收盘价 > SAR（SAR在价格下方，多头趋势），直接返回0（无空单信号）；
    *       2. 形态0（位置确认）：当前K线收盘价 < SAR（SAR在价格上方，压力位），返回形态0权重（趋势确认）；
    *       3. 形态1（转向信号）：前一根K线收盘价 > SAR（SAR曾在价格下方），当前K线收盘价 < SAR（SAR切换至上方），
    *          说明SAR完成“多头→空头”转向，直接返回形态1权重（优先级最高）；
    *       4. 信号优先级：形态1 > 形态0（转向信号标志趋势启动/反转，权重更高）
    */
   virtual int       ShortCondition(void);

protected:
   //----------------------------------------------------------------
   // 内部辅助方法：SAR 指标初始化（仅内部调用）
   //----------------------------------------------------------------
   /**
    * @brief 创建并初始化 SAR 指标（绑定品种、周期、参数，注册到指标集合）
    * @param indicators [in] 指标集合对象（用于管理 SAR 指标）
    * @return bool - 初始化结果：true=成功（指标创建+参数配置完成），false=失败
    * @note 内部流程：
    *       1. 检查指标集合指针有效性；
    *       2. 将 SAR 指标对象（m_sar）添加到指标集合；
    *       3. 调用 m_sar.Create() 绑定当前交易品种、周期及核心参数（步长、最大值）；
    *       4. 若添加或创建失败，输出错误日志并返回 false
    */
   bool              InitSAR(CIndicators *indicators);

   //----------------------------------------------------------------
   // 数据读取与差值计算：快捷获取指标与价格关系（保护，子类可直接调用）
   //----------------------------------------------------------------
   /**
    * @brief 获取指定索引的 SAR 指标值
    * @param ind [in] 索引（0=当前K线，1=前一根K线，以此类推）
    * @return double - SAR 指标值（价格上方=压力位，价格下方=支撑位，随趋势动态移动）
    */
   double            SAR(int ind);

   /**
    * @brief 获取指定索引的收盘价（封装父类价格序列读取逻辑）
    * @param ind [in] 索引（0=当前K线，1=前一根K线，以此类推）
    * @return double - 收盘价（SAR 信号判断的核心价格数据）
    */
   double            Close(int ind);

   /**
    * @brief 计算指定索引K线的收盘价与 SAR 的差值（反映两者位置关系）
    * @param ind [in] 索引（0=当前K线，1=前一根K线，以此类推）
    * @return double - 差值（>0=收盘价在SAR上方，<0=收盘价在SAR下方，=0=两者重合）
    */
   double            DiffClose(int ind);
  };
//+------------------------------------------------------------------+